package irc

import (
	"context"
	"encoding/json"
	"fmt"
	. "ircove.com/common"
	"log"
)

func SelectHander(request *Message) func(ctx context.Context, client *Client, request *Message) (response *Message) {

	if request == nil {
		log.Printf("SelectHander request  is null !")
		return nil
	}
	messagetype := request.Header.MessageType

	switch messagetype {
	case MessageType_RPC:
		return RpcController
	case MessageType_CTRL:
		return CtrlController
	case MessageType_Hub:
		return HubController
	case MessageType_HeartBeat:
		return HeartBeatController
	}
	return nil
}

func RpcController(ctx context.Context, client *Client, request *Message) (response *Message) {
	return hander(ctx, client, request)
}
func CtrlController(ctx context.Context, client *Client, request *Message) (response *Message) {
	return hander(ctx, client, request)
}

func HubController(ctx context.Context, client *Client, request *Message) (response *Message) {
	return hander(ctx, client, request)
	//var arg map[string]string
	//err := json.Unmarshal(request.Data,&arg)
	//if response= errorhandler(request,err,SerializeError);response!=nil{
	//  return  response
	//}
	// context:= &VFContext{
	// 	 Request:request,
	// 	 Args:arg,
	// }
	// fid :=request.Header.MessageID
	// cmd := FindCommand(fid)
	//if cmd !=nil {
	//	errorhandler(request,ObjecctNotFound,ObjecctNotFound)
	//}
	//vresult := cmd(context)
	//bytes, err:= json.Marshal(vresult)
	//errorhandler(request,SerializeError,SerializeError)
	//request.SetData(bytes)
	//return request
}

func hander(ctx context.Context, client *Client, request *Message) (response *Message) {

	//select {
	// case <-ctx.Done():
	// return errorhandler(request,CancelError,CancelError)
	// default:
	//
	//}
	var arg map[string]string = make(map[string]string, 10)
	if request.Header.MessageLen > 0 {
		err := json.Unmarshal(request.Data, &arg)
		if response = errorhandler(request, err, SerializeError); response != nil {
			return response
		}
	}
	context := &VFContext{
		Client:  client,
		Request: request,
		Args:    arg,
	}
	fid := request.Header.MessageID
	cmd := FindCommand(fid)
	if cmd == nil {
		var code = ObjecctNotFound.Clone(fmt.Sprintf("FindCommand Not Fonund MessageID: %d\n", fid))
		return errorhandler(request, code, code)
	}
	vresult := cmd(context)
	//bytes, err:= json.Marshal(vresult)
	//if response=errorhandler(request,err,SerializeError);response!=nil{
	//	return  response
	//}
	//request.SetData(bytes)
	////response ,err= request.Clone(bytes)
	////if err!=nil {
	////	log.Fatal(err)
	////	return errorhandler(request,err,ErrorArgument)
	////}
	//return request

	return VFResult_ToMessage(request, vresult)
}

func VFResult_ToMessage(request *Message, vresult *VFResult) (response *Message) {
	bytes, err := json.Marshal(vresult)
	if response := errorhandler(request, err, SerializeError); response != nil {
		return response
	}
	response,err =request.Clone(bytes)
	if err!=nil {
		log.Fatal(err)

	}

	return response
}

func errorhandler(request *Message, err error, code *VFCode) *Message {
	if err != nil {
		if err != code {
			err = code.Clone(err.Error())
		}
		bytes, err := json.Marshal(err)

		if err != nil {
			log.Fatal(err)
		}
		request.SetData(bytes)
		//response,err:=request.Clone(bytes)
		//if err!=nil {
		//	log.Fatal(err)
		//
		//}
		return request
	}
	return nil
}
func HeartBeatController(ctx context.Context, client *Client, request *Message) (response *Message) {
	return request
}
